AOP 简述

AOP,面向切面编程。其实并不是什么很深奥的理论,就是当你想在做完某个操作后,希望在这个操作的发生前,发生后,返回值后等等场景里,进行一些相应的操作时,不需要每次都要重复的写一遍相应的操作,而是把这些操作定义成一个切面,通过定义好相应的切点后,在操作发生时,由框架帮你把你所定义好的切面织入进来,从而让你再开发的过程中,只需要聚焦于业务即可,而不用每次去处理很多重复的细节。

AOP 的用处

AOP 最典型的应用是在数据库事务的管控中。比如要保存用户时,需要连同用户的角色一并保存如数据库,此时,用 OOP 无法完成这样的事务操作,而 AOP 可以完成这些事情。

AOP 开发细节

确定连接点

AOP 需要有连接点,即在什么时候触发。在 Spring 中就是某个类里的某个方法。

开发切面

切面用来描述各个过程中需要做什么,用 @Aspect 注解来定义切面。用 @Before、@After、@AfterReturning、@AfterThrowing 等注解来表示各个过程。

定义切点

Spring 里 定义了切点(Pointcut)的概念,切点的作用就是向 Spring 描述哪个类的哪个方法需要启用 AOP 编程。在切面里,切点的代码如下:

1
2
3

@Pointcut("execution(* com.xxx.xxx.xxxImpl.xxxfunction(..))")
public void pointCut(){};

代码中,用 @Pointcut 来定义切点,标注在 pointcut 方法上。 切点里的正则式含义如下:

  • execution 表示在执行的时候,拦截里面的正则匹配方法
    • 号表示任意返回类型的方法
  • com.xxx.xxx.xxxImpl 指定目标对象类的全限定名称
  • xxxfunction 指定目标对象类里的方法
  • (..)表示任意参数进行匹配

引入,增加切面

加入某个切面非自己提供的,不能修改它,而想对它进行补充的时候,Spring 允许通过为这个切面引入新的接口来增强这个切面的功能。
步骤如下:

1、 先定义需要引入的新接口

2、在切面里,通过 @DeclareParents 注解来引入,它有两个必须配置的属性 value 和 defaultImpl。

  • value: 指向你要增强功能的目标对象类
  • defaultImpl: 引入增强功能的类,即引入的接口的实现类。

多个切面

spring 支持多个切面的运行。在组织多个切面时,需要指定各个切面运行的顺序。

SPring 提供了 @Order 注解 和 Orderd 接口两种方式来指定切面的顺序。 实际使用中,用 @Order 比较方便,使用方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13

@Aspect
@Order(1)
public class MyAspect1 {

}


@Aspect
@Order(2)
public class MyAspect2 {

}